use strict ";
/**
 * 前端核心函数
 * 37798955@qq.com
 */



/**替换
 * @param {Object} reallyDo
 * @param {Object} replaceWith
 * @param {Object} ignoreCase
 */
String.prototype.replaceAll = function(reallyDo, replaceWith, ignoreCase) {
	if (!RegExp.prototype.isPrototypeOf(reallyDo)) {
		return this.replace(new RegExp(reallyDo, (ignoreCase ? "gi" : "gm")), replaceWith);
	} else {
		return this.replace(reallyDo, replaceWith);
	}
};
String.prototype.startWith = function(str) {
	if (str == null || str == "" || this.length == 0 || str.length > this.length)
		return false;
	if (this.substr(0, str.length) == str)
		return true;
	else
		return false;
	return true;
};
/**
 * 左侧补n个0
 * @param {Object} length
 */
String.prototype.padLeft = function(length) {
	var a = [];
	for (var i = this.length; i < length; i++) {
		a.push("0");
	}
	a.push(this);
	return a.join("");
};
String.prototype.parse = function(length) {
	try {
		return JSON.parse(this);
	} catch (e) {
		return null;
	}
}

/**
 * 保留精度
 * @param {Object} digit 精度位数
 */
Number.prototype.digit = function(digit) {
	var m = Math.pow(10, digit);
	return parseInt(this * m, 10) / m;
};
Date.prototype.addMonths = function(mons) {
	var date = new Date(this);
	date.setMonth(date.getMonth() + mons);
	return date;
};
Date.prototype.addDays = function(days) {
	var date = new Date(this);
	date.setDate(date.getDate() + days);
	return date;
};
Date.prototype.format = function(fmt) {
	if (fmt == null || fmt == '')
		fmt = 'yyyy-MM-dd hh:mm:ss'
	var d = new Date(this);
	var o = {
		"M+": d.getMonth() + 1, //月 
		"d+": d.getDate(), //日 
		"h+": d.getHours(), //时 
		"m+": d.getMinutes(), //分 
		"s+": d.getSeconds(), //秒 
		"q+": Math.floor((d.getMonth() + 3) / 3), //季度
		"S": d.getMilliseconds() //毫秒 
	};
	if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (d.getFullYear() + "").substr(4 - RegExp.$1.length));
	for (var k in o)
		if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[
			k]).substr(("" + o[k]).length)));
	return fmt;
};
/**
 * 转成日期数值格式
 */
Date.prototype.toDateNum = function() {
	var D = ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09'];
	var d = new Date(this);

	return [d.getFullYear(),
		D[d.getMonth() + 1] || d.getMonth() + 1,
		D[d.getDate()] || d.getDate()
	].join('')
};
/**
 * 转成时间数值格式
 */
Date.prototype.toTimeNum = function() {
	var D = ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09'];
	var d = new Date(this);
	return [D[d.getHours()] || d.getHours(),
		D[d.getMinutes()] || d.getMinutes(),
		D[d.getSeconds()] || d.getSeconds(),
		d.getMilliseconds().toString().padLeft(4)
	].join('');
};


/**
 * 功能:实现VBScript的DateAdd功能.
 *   参数:interval,字符串表达式，表示要添加的时间间隔.
 *   参数:number,数值表达式，表示要添加的时间间隔的个数.
 *   返回:新的时间对象.
 * @param {Object} interval 类型 年y 季度q 月M 周w 天 d 小时h 分钟 m 秒 s 默认：天
 * @param {Object} number 加数
 */
Date.prototype.add = function(interval, number) {
	var d = this;
	switch (interval) {
		case "y":
			d.setFullYear(d.getFullYear() + number);
			return d;
		case "q":
			d.setMonth(d.getMonth() + number * 3);
			return d;
		case "M":
			d.setMonth(d.getMonth() + number);
			return d;
		case "w":
			d.setDate(d.getDate() + number * 7);
			return d;
		case "h":
			d.setHours(d.getHours() + number);
			return d;
		case "m":
			d.setMinutes(d.getMinutes() + number);
			return d;
		case "s":
			d.setSeconds(d.getSeconds() + number);
			return d;
		default:
			d.setDate(d.getDate() + number);
			return d;
	}
};
/**
 * 删除空的元素
 */
Array.prototype.trim = function() {
	if (this == null || this.length < 1) return [];
	var arr = [];
	for (var i = 0; i < this.length; i++) {
		if (this[i] == null || this[i] == undefined || this[i] == "") {
			continue;
		}
		arr.push(this[i]);
	}
	return arr;
};

//千万不能给object prototype添加方法
(function(t) {
	if ("object" == typeof exports && "object" == typeof module) module.exports = t();
	else if ("function" == typeof define && define.amd) define([], t);
	else if ("object" == typeof exports) exports._IS = t();
	else {
		var glob;
		try {
			glob = window;
		} catch (err) {
			glob = self;
		}
		glob._IS = t(); //静态函数库
	}
})(
	function() {
		var _IS = {};
		var gettype = Object.prototype.toString;

		_IS.isMap = function(o) {
			return gettype.call(o) == "[object Object]";
		}
		_IS.isArray = function(o) {
			return gettype.call(o) == "[object Array]";
		}
		_IS.isFun = function(o) {
			return gettype.call(o) == "[object Function]";
		}
		_IS.isNULL = function(o) {
			return gettype.call(o) == "[object Null]";
		}
		_IS.isUndefined = function(o) {
			return gettype.call(o) == "[object Undefined]";
		}
		_IS.isNum = function(o) {
			return gettype.call(o) == "[object Number]";
		}
		_IS.isString = function(o) {
			return gettype.call(o) == "[object String]";
		}
		_IS.isBool = function(o) {
			return gettype.call(o) == "[object Boolean]";
		}
		_IS.isEmpty = function(obj) {
			if (obj === undefined || obj === null || obj == "" || obj == "null") {
				return true;
			} else return false;
		}
		_IS.isEmptyMap = function(e) {
			if (e == undefined || e == null)
				return true;
			for (var t in e)
				return false;
			return true;
		}
		_IS.isEmptyArray = function(arr) {
			if (arr = undefined || _IS.isArray(arr) || arr.length == 0)
				return true;
			else
				return false;
		}
		return _IS;
	});

(function(t) {
	if ("object" == typeof exports && "object" == typeof module) module.exports = t();
	else if ("function" == typeof define && define.amd) define([], t);
	else if ("object" == typeof exports) exports._Fun = t();
	else {
		var glob;
		try {
			glob = window;
		} catch (err) {
			glob = self;
		}
		glob._Fun = t(); //静态函数库
	}
})(function(undefined) {
	var f = {
		o: {}, //万能对象类
		a: {}, //数组类型
		m: {}, //map对象类
		d: {}, //日期类
		n: {}, //数值类
		s: {}, //字符类
		pr: {} //打印类		
	};

	f.n.addMonnum = function(monnum, num) {
		var ym = new Number(monnum)
		var y = parseInt(ym / 100); //2017
		var m = ym % 100; //09
		var cnt = parseInt(num / 12);
		var mnt = num % 12;
		y = y + cnt;
		if (mnt < 0) {
			y = y - 1;
			m = m + (12 + mnt);
		} else {
			m = m + mnt;
		}
		if (m > 12) {
			y = y + 1;
			m -= 12;
		}
		return (y * 100 + m).toString();
	};

	/**放大
	 * @param {Object} f
	 * @param {Object} n n如果小于10  10^n  如果大于10 就是
	 */

	f.n.Zoomin = function(f, n) {
		return f * n;
	};

	/**缩小
	 * @param {Object} f
	 * @param {Object} n
	 */

	f.n.Zoomout = function(f, n) {
		return f / n;
	};
	/**左侧补0
	 * @param {Object} obj
	 * @param {Object} length
	 */
	f.s.padLeft = function(obj, length) {
		return obj.toString().padLeft(length);
	};

	f.s.getGuid = function() {
		var d = new Date().getTime();
		var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
			var r = (d + Math.random() * 16) % 16 | 0;
			d = Math.floor(d / 16);
			return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
		});
		return uuid;
	}


	/**
	 * 把有分隔符的字符串转成数组或者对象
	 * 如果已经是数组或者对象则不用转化
	 * @param {String ，Array ，Map} obj 
	 */
	function split(obj, sp) {
		var props = null;
		sp = (sp == undefined || sp == null) ? "," : sp;
		if (_IS.isEmpty(obj)) return null;
		if (_IS.isString(obj))
			props = obj.split(sp);
		else
			props = obj;
		return props;
	}
	f.s.split = split;
	/**
	 * 测试打印json对象
	 * @param {Object} data
	 * @param {Object} note
	 */
	f.pr.json = function(data, note) {
		var s = JSON.stringify(data);
		if (note == null)
			console.log(s)
		else
			console.log(note, s)
	};
	/**
	 * 测试打印map对象
	 * @param {Object} data
	 * @param {Object} note
	 */
	f.pr.map = function(m) {
		for (var i in map) {
			console.log(i, JSON.stringify(map[i]));
		}
	};

	function equal(a, b) {
		if ((null == a && null == b) || (undefined == a && undefined == b)) return true;
		var classNameA = toString.call(a),
			classNameB = toString.call(b);
		if (classNameA == '[object Function]') return false;
		switch (classNameA) {
			case '[object RegExp]':
			case '[object String]':
				//进行字符串转换比较
				return '' + a === '' + b;
			case '[object Number]':
				//进行数字转换比较,判断是否为NaN
				if (+a !== +a) {
					return +b !== +b;
				}
				//判断是否为0或-0
				return +a === 0 ? 1 / +a === 1 / b : +a === +b;
			case '[object Date]':
			case '[object Boolean]':
				return +a === +b;
		}
		if (classNameA == '[object Array]') {
			for (var i = 0; i < a.length; ++i) {
				if (!equal(a[i], b[i])) return false;
			}
			return true;
		}
		if (classNameA == '[object Object]') {
			for (var i in a) {
				if (!equal(a[i], b[i])) return false;
			}
			return true;
		}
		return false;
	}
	f.o.equal = equal;
	/**
	 * 在数组arr1的第n位之前，插入arr2元素
	 * @param {Object} arr1 待插入的数组
	 * @param {Object} n  第n位之前
	 * @param {Object} arr2 插入arr2数组
	 */
	function insert(arr1, n, arr2) {
		if (arr2 == null || arr2 == undefined) return arr1;
		n = (n > arr1.length) ? arr1.length : (n < 0) ? arr1.length + n : n;
		for (var i = arr2.length - 1; i >= 0; i--) {
			arr1.splice(n, 0, arr2[i]);
		}
		return arr1;
	}
	f.a.insert = insert;
	/**
	 * 移动数组中的一个元素从i 到 n位后面
	 * @param {Object} arr1 数组
	 * @param {Object} i 移动前的开始位置
	 * @param {Object} n 移动前的目标位置之后
	 * @param {Object} len 移动元素个数
	 */
	function move(arr1, a, n, len) {
		if (len == null || len == undefined) return arr1;
		//var a = arr1.slice(i, i + len);
		if (a == n || a < 0 || len < 1 || len > arr1.length) return arr1;
		var b;
		if (a > n) {
			b = a;
			a = n;
			n = b;
		}
		if (a + len > n) return arr1;
		var k = n - a - len;
		for (var i = len - 1; i >= 0; i--) {
			for (var j = 0; j <= k; j++) {

				var z = a + i + j;
				change(arr1, z, z + 1);
			}
		}
		return arr1;
	}
	f.a.move = move;

	function change(arr1, a, a1) {
		var z
		z = arr1[a];
		arr1[a] = arr1[a1];
		arr1[a1] = z;
	}
	/**
	 * 交换数组 a位置和n位置的 元素 长度为len
	 * @param {Object} arr1
	 * @param {Object} a
	 * @param {Object} n
	 * @param {Object} len
	 */
	f.a.exchange = function(arr1, a, n, len) {
		if (len == null || len == undefined) return arr1;
		//var a = arr1.slice(i, i + len);
		if (a == n || a < 0 || len < 1 || len > arr1.length) return arr1;
		var b;
		if (a > n) {
			b = a;
			a = n;
			n = b;
		}
		if (a + len > n) return arr1;
		var k = n - a;
		for (var i = 0; i < len; i++) {
			change(arr1, a + i, n + i);
		}
		return arr1;

	}
	/**
	 * 拼接数组（不平面化）直接用join
	 * 拼接数组（只对第二层平面化） 用concat ,为空的不丢弃
	 * 参数个数可变
	 * a=[1,2,3] ,b=[3，4]
	 * c.concat(a,b) =[1,2,3,3,4]
	 */
	f.a.concat = function() {
		var arr = [];
		for (var i = 0; i < arguments.length; i++) {
			var item = arguments[i];
			if (_IS.isArray(item)) {
				for (var j = 0; j < item.length; j++) {
					arr.push(item[j]);
				}
			} else {
				if (_IS.isEmpty(item)) return [];
				arr.push(item);
			}
		}
		return arr;
	}
	/**
	 * 适用于 【字符串，字符串】类型
	 * 不剔除空值，
	 * @param {Object} arr
	 */
	f.a.distinct = function(arr) {
		var arr1 = []
		for (var i = 0; i < arr.length; i++) {
			//if (_IS.isEmpty(arr[i])) continue;
			var flag = true;
			for (var j = 0; j < arr1.length; j++) {
				if (equal(arr1[j], arr[i])) {
					flag = false;
					break;
				}
			}
			if (flag)
				arr1.push(arr[i])
		}
		return arr1;
	}

	/**
	 * 查找数组中的位置
	 * @param {Object} arr 待匹配的数组
	 * @param {Object} obj 匹配的对象
	 * find() 在ie11 之前不支持
	 */
	f.a.indexOf = function(arr, obj) {
		for (var i = 0; i < arr.length; i++) {
			if (equal(arr[i], obj)) return i;
		}
		return -1;
	};

	/**
	 * 深度克隆
	 * @param {Object} obj 待克隆的map对象
	 * @param {Object} attrs 对于map类型的对象 可以限定克隆的属性 ，数组格式
	 */
	function clone(obj, attrs) {
		if (undefined == obj || null == obj) return null;
		if (obj instanceof Date) {
			var copy = new Date();
			copy.setTime(obj.getTime());
			return copy;
		}
		if (obj instanceof Array) {
			var copy = [];
			for (var i = 0; i < obj.length; ++i) {
				copy.push(clone(obj[i], attrs));
			}
			return copy;
		}
		if (obj instanceof Object) {
			var copy = {};
			if (attrs == null) {

				for (var attr in obj) {
					copy[attr] = obj[attr];
				}
			} else {
				for (var a = 0; a < attrs.length; a++) {
					copy[attrs[a]] = obj[attrs[a]];
				}
			}
			return copy;
		}
		return obj;
	}
	f.o.clone = clone;

	/**
	 * 对比两个Map对象的特定属性 判断是否相等
	 * @param {Map} obj1 Map
	 * @param {Map} obj2 Map
	 * @param {Array} cols  待对比的键
	 */
	f.m.equal = function(obj1, obj2, cols) {
		var keys = split(cols);
		if (keys == null) return false;
		for (var i = 0; i < keys.length; i++) {
			var field = keys[i];
			if (!equal(obj1[field], obj2[field])) {
				return false;
			}
		}
		return true;
	};

	//对象合并可以使用 Object.assign函数

	/**
	 * 根据属性,截取object对象的部分属性 生成新的对象
	 * @param {Object} object
	 * @param {String，Array} cols 字段集合
	 */
	function section(object, cols) {
		var n1 = {};
		var props = split(cols);
		if (null == props) return null;
		for (var i = 0; i < props.length; i++) {
			n1[props[i]] = object[props[i]];
		}
		return n1;
	}
	f.m.section = section;

	/**
	 * 合并o1和o2 生成新的对象,可以只选择抽取o1和o2中的部分字段
	 * @param {Map} o1
	 * @param {Map} o2
	 * @param {Object} o1fields
	 * @param {Object} o2fields
	 */
	function merge(o1, o2, o1fields, o2fields) {
		var a = section(o1, o1fields);
		var b = section(o2, o2fields);
		return Object.assign(a, b);
	}
	f.m.merge = merge;

	return f;
});


(function(t) {
	if ("object" == typeof exports && "object" == typeof module) module.exports = t();
	else if ("function" == typeof define && define.amd) define([], t);
	else if ("object" == typeof exports) exports._FF = t();
	else {
		var glob;
		try {
			glob = window;
		} catch (err) {
			glob = self;
		}
		glob._FF = t(); //静态函数库
	}
})(
	function() {
		var _FF = {};
		/**
		 *  把值写入 从表单元素 
		 * @param {Object} targetid 从表单元素
		 * @return 数值
		 */
		_FF.putV = function(targetid, obj) {
			var tag = document.getElementById(targetid)
			if (tag == null)
				return;
			if (tag.tagName == "INPUT" || tag.tagName == "TEXTAREA") {
				tag.value = obj;
			} else if (tag.tagName == "DIV" || tag.tagName == "SPAN") {
				tag.innerHTML = obj;
			}
		}
		/**
		 *  返回 从表单元素  的 value， 并转成数值
		 * @param {Object} targetid 从表单元素
		 * @return 数值
		 */
		_FF.getN = function(targetid, def) {
			var o = _FF.getV(targetid);
			var i = Number(o);
			if (isNaN(i)) {
				if (isNaN(def)) {
					return 0;
				} else {
					return def;
				}
			}
			return i;
		}
		/**
		 *  返回 从表单元素  的 value
		 * @param {Object} targetid 从表单元素
		 * @return keyvalue对 
		 */
		_FF.getV = function(targetid) {
			var tag = document.getElementById(targetid);
			if (tag == null)
				return null;
			var obj = '';
			if (tag.tagName == "INPUT" || tag.tagName == "TEXTAREA") {
				obj = tag.value;
			} else if (tag.tagName == "DIV") {
				obj = tag.innerHTML;
			}

			return obj;
		}
		/**
		 * 从row 中匹配key属性值=value 的对象
		 * @param {Object} row [{value:,text:},...] 数组格式
		 * @param {Object} value 待匹配的键值
		 * @param {Object} k 键的名称 数组格式 【k1，k2】
		 * @return 从row 中匹配到的对象
		 */
		_FF.ToM = function(row, value, key) {
			if (!_IS.isArray(row)) return null;
			var fis = []; //'value'
			if (_is.isEmpty(key)) {
				fis.push('value');
			} else if (_IS.isString(key)) {
				fis.push(key);
			} else if (_IS.isArray(key)) {
				fis = key;
			} else {
				return null;
			}
			for (var i = 0; i < row.length; i++) {
				var flag = true;
				for (var j = 0; j < fis.length; j++) {
					if (row[i][fis[j]] != value[j]) {
						flag = false;
						break;
					}
				}
				if (flag) {
					return row[i];
				}
			}
			return null;
		}
		/**
		 *  把 keyvalue对 付给从表单元素 
		 * @param {Object} targetid 表单元素 
		 * @param {Object} obj keyvalue对 
		 */
		_FF.putM = function(targetid, obj) {
			//console.log(JSON.stringify(obj))
			var tag = document.getElementById(targetid)
			if (tag == null)
				return;
			if (obj == null)
				obj = {
					text: null,
					value: null
				};
			if (tag.tagName == "INPUT" || tag.tagName == "TEXTAREA") {
				tag.value = obj.text;
			} else if (tag.tagName == "DIV") {
				tag.innerHTML = obj.text;
			}
			tag.extdata = obj.value;
		}
		/**
		 *  根据 返回 从表单元素  的 keyvalue对 
		 * @param {Object} targetid 从表单元素
		 * @return keyvalue对 
		 */
		_FF.getM = function(targetid) {
			var obj = {
				text: null,
				value: null
			};
			var tag = document.getElementById(targetid);
			if (tag == null)
				return obj;
			if (tag.tagName == "INPUT" || tag.tagName == "TEXTAREA") {
				obj.text = tag.value;
			} else if (tag.tagName == "DIV") {
				obj.text = tag.innerHTML;
			}
			obj.value = tag.extdata;
			return obj;
		}
		/**
		 * 查找有class=cls的元素
		 * @param {Object} dom dom元素
		 * @param {Object} cls 类目
		 * @return 找到返回true;否则返回 false
		 */
		_FF.hasClass = function(dom, cls) {
			var obj_class = dom.className, //获取 class 内容.
				obj_class_lst = obj_class.split(/\s+/); //通过split空字符将cls转换成数组.
			x = 0;
			for (x in obj_class_lst) {
				if (obj_class_lst[x] == cls) { //循环数组, 判断是否包含cls
					return true;
				}
			}
			return false;
		}
		return _FF;
	});
